#coding=utf-8
import imutils
from skimage import exposure
import numpy as np
import argparse
import cv2,os
from  glob import glob
import matplotlib.pyplot as plt
from scipy import ndimage

def crossp(p01,p23):
    p0,p1=p01
    p2, p3 = p23

    x0, y0 = p0
    x1, y1 = p1
    x2, y2 = p2
    x3, y3 = p3

    if y2==y3:
        y=y2
        x= (x1-x0)/(y1-y0)(y-y1)+x1
    else:

        y = ((y0 - y1) * (y3 - y2) * x0 + (y3 - y2) * (x1 - x0) * y0 + (y1 - y0) * (y3 - y2) * x2 + (x2 - x3) *
             (y1 - y0) * y2) / ((x1 - x0) * (y3 - y2) + (y0 - y1) * (x3 - x2))
        x = x2 + (x3-x2)*(y-y2) / (y3-y2)
    return [x,y]

def rectangle_detect(image):
    image = imutils.resize(image, height=1000)
    ori_image = image.copy()
    # cv2.imshow('ori',image)
    # cv2.waitKey(0)

    img_midfilt = ndimage.median_filter(image, 5)
    gray_filt = cv2.cvtColor(img_midfilt, cv2.COLOR_BGR2GRAY)
    canny =cv2.Canny(gray_filt,70,70*3)
    row1, col1 = canny.shape


    kernel_d = np.array([[0,1,0],
                         [1,1,1],
                         [0,1,0]
                         ]).astype(np.uint8)
    dilated = cv2.dilate(canny, kernel_d)

    # hough line with proba
    lines = cv2.HoughLinesP(dilated, 1, np.pi / 180, threshold=int(row1*0.2),
                            minLineLength=int(row1*0.2), maxLineGap=int(row1*0.05))
    h1 = dilated * 0
    if lines is not None:
        for l in lines:
            cv2.line(h1, (l[0][0], l[0][1]), (l[0][2], l[0][3]), (255, 255, 255), 5)

    borders = {'top':{'y_left':[],'y_right':[]},
               'bottom':{'y_left':[],'y_right':[]},
               'left': {'x_top': [], 'x_bottom': []},
               'right': {'x_top': [], 'x_bottom': []},
               }
    # hough line
    lines = cv2.HoughLines(h1, 1, np.pi / 180, int(row1*0.2))
    hl2 = h1 * 0
    if lines is not None:
        for line in lines:
            line = line[0]
            rho = line[0]
            theta = line[1]

            x0 = np.cos(theta) * rho
            y0 = np.sin(theta) * rho

            if (theta < (np.pi / 15.)) or (theta > (14. * np.pi / 15.0)):
                # ver
                pt1 = (int(rho / np.cos(theta)), 0)
                pt2 = (int((rho - hl2.shape[0] * np.sin(theta)) / np.cos(theta)), hl2.shape[0])

                if pt1[0] < col1 * 0.5 and pt2[0] < col1 * 0.5:
                    # left border
                    if pt1[1]<pt2[1]:
                        borders['left']['x_top'].append(pt1[0])
                        borders['left']['x_bottom'].append(pt2[0])
                    else:
                        borders['left']['x_top'].append(pt2[0])
                        borders['left']['x_bottom'].append(pt1[0])
                else:
                    # right border
                    if pt1[1]<pt2[1]:
                        borders['right']['x_top'].append(pt1[0])
                        borders['right']['x_bottom'].append(pt2[0])
                    else:
                        borders['right']['x_top'].append(pt2[0])
                        borders['right']['x_bottom'].append(pt1[0])


                # cv2.line(h2, pt1, pt2, (255), 2)
            elif (theta > (5 * np.pi / 12.)) and (theta < (7. * np.pi / 12.0)):
                pt1 = (0, int(rho / np.sin(theta)))
                pt2 = (hl2.shape[1], int((rho - hl2.shape[1] * np.cos(theta)) / np.sin(theta)))

                if pt1[1] < row1 * 0.5 and pt2[1] < row1 * 0.5:
                    # top border
                    if pt1[0]<pt2[0]:
                        borders['top']['y_left'].append(pt1[1])
                        borders['top']['y_right'].append(pt2[1])
                    else:
                        borders['top']['y_left'].append(pt2[1])
                        borders['top']['y_right'].append(pt1[1])

                elif pt1[1] > row1 * 0.5 and pt2[1] > row1 * 0.5:
                    # bottom border
                    if pt1[0]<pt2[0]:
                        borders['bottom']['y_left'].append(pt1[1])
                        borders['bottom']['y_right'].append(pt2[1])
                    else:
                        borders['bottom']['y_left'].append(pt2[1])
                        borders['bottom']['y_right'].append(pt1[1])
                # cv2.line(h2, pt1, pt2, (255), 2)
    # #draw borders
    corners = {}
    for posi in borders.keys():

        border = borders[posi]
        if posi == 'bottom':
            # if len(border['y_left'])==0:
            #     print '%s border missing'%(posi)
            #     return
            y1 = int(row1*0.8)
            y2 = int(row1*0.8)
            pt1 = (0,y1)
            pt2 = (col1,y2)
            cv2.line(hl2, pt1, pt2, (255,), 1)

        elif posi in ['left','right']:
            if len(border['x_top'])==0:
                print '%s border missing'%(posi)
                return
            x1 = int(np.mean(border['x_top']))
            x2 = int(np.mean(border['x_bottom']))
            pt1 = (x1,0)
            pt2 = (x2,row1)
            cv2.line(hl2, pt1, pt2, (255,), 1)
        else:
            if len(border['y_left'])==0:
                print '%s border missing'%(posi)
                return
            y1 = int(np.mean(border['y_left']))
            y2 = int(np.mean(border['y_right']))
            pt1 = (0,y1)
            pt2 = (col1,y2)
            cv2.line(hl2, pt1, pt2, (255,), 1)

        corners[posi] = [pt1,pt2]

    top_left = crossp(corners['top'],corners['left'])
    top_right = crossp(corners['top'], corners['right'])
    bottom_left = crossp(corners['bottom'], corners['left'])
    bottom_right = crossp(corners['bottom'], corners['right'])

    # plt.figure(figsize=(15,8))
    # plt.subplots_adjust(top=0.95,bottom=0.05,left=0.05,right=0.95,hspace=0.15, wspace=0.01)
    # plt.subplot(221)
    # plt.title('img')
    # plt.imshow(canny)
    #
    # plt.subplot(222)
    # plt.title('dilated')
    # plt.imshow(dilated)
    #
    # plt.subplot(223)
    # plt.title('h1')
    # plt.imshow(h1)
    #
    # plt.subplot(224)
    # plt.title('h2')
    # plt.imshow(h2)
    # plt.show()
    h1 =  bottom_left[1]-top_left[1]
    h2 =  bottom_right[1]-top_right[1]
    w1 = top_right[0]-top_left[0]
    w2 = bottom_right[0]-bottom_left[0]

    top_left[0] = int(top_left[0]+0.05*0.5*(w1+w2))
    top_right[0] = int(top_right[0] - 0.05 * 0.5 * (w1 + w2))
    bottom_left[0] = int(bottom_left[0] + 0.05 * 0.5 * (w1 + w2))
    bottom_right[0] = int(bottom_right[0] - 0.05 * 0.5 * (w1 + w2))

    top_left[1] = int(top_left[1] + 0.05 * 0.5 * (h1 + h2))
    top_right[1] = int(top_right[1] + 0.05 * 0.5 * (h1 + h2))
    bottom_left[1] = int(bottom_left[1] - 0.05 * 0.5 * (h1 + h2))
    bottom_right[1] = int(bottom_right[1] - 0.05 * 0.5 * (h1 + h2))

    return [tuple(top_left),
            tuple(top_right),
            tuple(bottom_right),
            tuple(bottom_left)], hl2



if __name__ == '__main__':
    img = cv2.imread("data/DSC_1375.jpg")
    rectangle_detect(img)

